package com.zzuli.yxypre.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzuli.yxypre.comment.R;
import com.zzuli.yxypre.entity.*;
import com.zzuli.yxypre.mapper.*;
import com.zzuli.yxypre.service.SheetService;
import com.zzuli.yxypre.utils.JwtUtils;
import com.zzuli.yxypre.utils.TXCloudFileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @auther pony
 * @create 2023-05-09 13:38
 */
@Service
public class SheetServiceImpl extends ServiceImpl<SheetMapper, Sheet> implements SheetService {

    @Autowired
    private SheetMapper sheetMapper;

    @Autowired
    private LoveMapper loveMapper;

    @Autowired
    private SongMapper songMapper;

    @Autowired
    private ThumbsMapper thumbsMapper;

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private UserMapper userMapper;

    // 歌单创建默认图片
    private String sheetImg = "https://pony-1312090731.cos.ap-beijing.myqcloud.com/yxy/images/sheet-default.png";

    // 图片存储的文件夹
    private static String imgPath = "yxy/images/";

    //腾讯云对象存储 路径-访问域名
    private static String url = "https://pony-1312090731.cos.ap-beijing.myqcloud.com/";

    /**
     * 根据 歌单 id 获取一张 歌单信息
     * @param id 歌单id
     * @return
     */
    @Override
    public R getOneById(Integer id, HttpServletRequest request) {
        // 获取登录用户id
        Integer userId = Integer.valueOf(JwtUtils.getUserIdByJwtToken(request));
        Sheet sheet = sheetMapper.selectById(id);
        if (sheet.getType()!=null&&!"".equals(sheet.getType())){
            // 封装 sheet 的标签信息
            // pony,pony1,
            String typeStr = sheet.getType();
            // 去掉末尾的,
            String type = typeStr.substring(0, typeStr.length() - 1);
            // 将字符串转化为list
            List tagList = Arrays.asList(type.split(","));
            sheet.setTagList(tagList);
        }
        // 封装创建 sheet 的用户信息
        List<User> userList = sheetMapper.selectUserBySheetId1(sheet.getId());
        sheet.setUserList(userList);
        // 封装 sheet 下的歌曲信息
        List<Song> songList = sheetMapper.selectSongBySheetId(sheet.getId());
        sheet.setSongList(songList);
        // 判断歌单是否被当前登录用户所喜欢
        LambdaQueryWrapper<Love> loveQw = new LambdaQueryWrapper<>();
        // 歌曲 type 是 3
        loveQw.eq(Love::getType, 3);
        loveQw.eq(Love::getUserId, userId);
        loveQw.eq(Love::getRelevance, sheet.getId());
        Love love = loveMapper.selectOne(loveQw);
        if (!Objects.isNull(love)){
            sheet.setIsLove(1);
        }else {
            sheet.setIsLove(0);
        }

        // 封装 歌曲信息
        for (Song song : songList) {
            // 判断歌曲是否被当前登录用户所喜欢
            LambdaQueryWrapper<Love> loveQw1 = new LambdaQueryWrapper<>();
            // 歌曲 type 是 1
            loveQw1.eq(Love::getType, 1);
            loveQw1.eq(Love::getUserId, userId);
            loveQw1.eq(Love::getRelevance, song.getSongId());
            Love love1 = loveMapper.selectOne(loveQw1);
            if (!Objects.isNull(love1)){
                song.setIsLove(1);
            }else {
                song.setIsLove(0);
            }

            // 封装歌曲的歌手信息
            // 查询歌手
            List<Singer> singerList = songMapper.selectSingerBySongId(song.getSongId());
            song.setSinger(singerList);
            // 查询专辑
            List<Album> albumList = songMapper.selectAlbumBySongId(song.getSongId());
            song.setAlbum(albumList);
        }

        //封装歌单的评论数
        Integer commentCount = sheetMapper.selectSheetCommentCountBySheetId(id);
        sheet.setCommentCount(commentCount);

        // 封装歌单是否是当前用户创建的
        List<User> userList1 = sheetMapper.selectUserBySheetId(sheet.getId(), userId);
        if(userList1 != null && !userList1.isEmpty()){
            sheet.setIsEdit(1);
        }else {
            sheet.setIsEdit(0);
        }
        return R.success().message("根据歌单id，获取单个歌单信息成功").data("sheet", sheet);
    }

    /**
     * 获取歌单的分页评论数据
     * @param order 排序关键字
     * @param sheetId 歌单id
     * @param pageCurrent 当前页
     * @param pageSize 每页大小
     * @return
     */
    @Override
    public R commentPage(String order, Integer sheetId, Integer pageCurrent, Integer pageSize, HttpServletRequest request) {
        // 获取登录用户id
        Integer userId = Integer.valueOf(JwtUtils.getUserIdByJwtToken(request));
        // 根据热度降序排序并分页
        // 计算 limit 参数1
        Integer limit1 = (pageCurrent - 1) * pageSize;
        List<Comment> commentList = null;
        if ("hot".equals(order)){
            commentList = commentMapper.commentHotDesc(sheetId, 3, 1, limit1, pageSize);
        }else if("time".equals(order)){
            commentList = commentMapper.commentTimeDesc(sheetId, 3, 1, limit1, pageSize);
        }
        LambdaQueryWrapper<Comment> qw = new LambdaQueryWrapper<>();
        qw.eq(Comment::getTableType,3);
        qw.eq(Comment::getRelevance, sheetId);
        qw.eq(Comment::getType, 1);
        Integer total = commentMapper.selectCount(qw);
        PageInfo pageInfo = new PageInfo(pageCurrent, pageSize, total, commentList);
        for (Comment comment : commentList) {
            comment.setOrder("time");
            // 封装评论人的信息
            User user = userMapper.selectById(comment.getUserId());
            comment.setUser(user);
            // 评论是否被当前登录用户点赞
            LambdaQueryWrapper<Thumbs> thumbsQw = new LambdaQueryWrapper<>();
            thumbsQw.eq(Thumbs::getUserId, userId);
            thumbsQw.eq(Thumbs::getCommentId, comment.getId());
            Thumbs thumbsSelectResult = thumbsMapper.selectOne(thumbsQw);
            if (!Objects.isNull(thumbsSelectResult)){
                comment.setIsThumbs(1);
            }else {
                comment.setIsThumbs(0);
            }
            // 评论总的点赞数
            LambdaQueryWrapper<Thumbs> thumbsQw1 = new LambdaQueryWrapper<>();
            thumbsQw1.eq(Thumbs::getCommentId, comment.getId());
            comment.setThumbsCount(thumbsMapper.selectCount(thumbsQw1));

            // 封装评论的回复
            // 根据评论 id 查询评论的回复
            LambdaQueryWrapper<Comment> replyQw = new LambdaQueryWrapper<>();
            replyQw.eq(Comment::getTableType, 3);
            replyQw.eq(Comment::getRelevance, comment.getId());
            List<Comment> replyList = commentMapper.selectList(replyQw);
            // 封装评论回复数
            comment.setCommentCount(replyList.size());
            // 回复的回复
            for (Comment reply : replyList) {
                // 封装评论的回复的回复人信息
                User replyer = userMapper.selectById(reply.getUserId());
                reply.setUser(replyer);

                // 评论是否被当前登录用户点赞
                LambdaQueryWrapper<Thumbs> replyThumbsQw = new LambdaQueryWrapper<>();
                replyThumbsQw.eq(Thumbs::getUserId, userId);
                replyThumbsQw.eq(Thumbs::getCommentId, reply.getId());
                Thumbs thumbsResult = thumbsMapper.selectOne(replyThumbsQw);
                if (!Objects.isNull(thumbsResult)){
                    reply.setIsThumbs(1);
                }else {
                    reply.setIsThumbs(0);
                }
                // 评论总的点赞数
                LambdaQueryWrapper<Thumbs> replyThumbsQw1 = new LambdaQueryWrapper<>();
                replyThumbsQw1.eq(Thumbs::getCommentId, reply.getId());
                reply.setThumbsCount(thumbsMapper.selectCount(replyThumbsQw1));

                // 回复的回复
                if(reply.getTargetId()!=0){
                    // 设置被回复人的信息
                    User targetUser = userMapper.selectById(reply.getTargetId());
                    reply.setTargetUser(targetUser);
                }

            }
            comment.setReply(replyList);
        }
        return R.success().message("歌单分页评论").data("commentPage", pageInfo);
    }

    /**
     * 为歌单，添加评论
     * @param comment
     * @param request
     * @return
     */
    @Override
    public R addComment(Comment comment, HttpServletRequest request) {
        // 1、根据 token 获取登录用户的id
        String id = String.valueOf(JwtUtils.getUserIdByJwtToken(request));
        // 2、封装评论信息
        // 评论人id
        comment.setUserId(Integer.valueOf(id));
        // 评论时间
        comment.setTime(new Date());
        int insertResult = commentMapper.insert(comment);
        if(insertResult==1){
            return R.success().message("歌单评论添加成功");
        }
        return R.error().message("歌单评论添加失败，系统错误请联系管理员！");
    }


    /**
     * 为歌单评论点赞
     * @param commentId 评论id
     * @param flag 1：点赞 0：取消点赞
     * @param request
     * @return
     */
    @Override
    public R thumbs(Integer commentId, Integer flag, HttpServletRequest request) {
        // 1、根据 token 获取登录用户的id
        Integer userId = Integer.valueOf(JwtUtils.getUserIdByJwtToken(request));
        LambdaQueryWrapper<Thumbs> qw = new LambdaQueryWrapper<>();
        qw.eq(Thumbs::getUserId, userId);
        qw.eq(Thumbs::getCommentId, commentId);
        // 取消点赞
        if (flag==0){
            thumbsMapper.delete(qw);
        }else { //点赞
            Thumbs thumbs = new Thumbs();
            thumbs.setUserId(userId);
            thumbs.setCommentId(commentId);
            thumbsMapper.insert(thumbs);
        }
        return R.success().message("点赞获取消点赞成功！");
    }

    /**
     * 修改歌单 type 标签
     * @param id
     * @param tagArr
     * @return
     */
    @Override
    public R addType(Integer id, String[] tagArr) {
        Sheet sheet = sheetMapper.selectById(id);
        // 去重
        //实例化一个set集合
        Set set = new HashSet();
        //遍历数组并存入集合,如果元素已存在则不会重复存入
        for (int i = 0; i < tagArr.length; i++) {
            set.add(tagArr[i]);
        }
        //返回Set集合的数组形式
        Object[] array = set.toArray();
        for (Object o : array) {
            System.out.println(o);
        }
        //        String[] tagDistinctArr = (String[]) set.toArray();
        String[] tagDistinctArr = (String[])(set.toArray(new String[set.size()]));

        String tagStr = "";
        for (String tag : tagDistinctArr) {
            tagStr = tagStr + tag + ",";
        }
        sheet.setType(tagStr);
        sheetMapper.updateById(sheet);
        return R.success().message("歌单标签修改成功");
    }

    /**
     * 添加歌单
     * 歌单图片，请参考上面的上传方法
     * @param sheet
     * @return
     */
    @Override
    public R addSheet(Sheet sheet, HttpServletRequest request) {
        // 1、判断用户是否上传了图片，没有上传一个默认的图片
        if("".equals(sheet)||sheet==null){
            // 设置歌单默认图片
            sheet.setImg(sheetImg);
        }
        // 获取登录用户id
        Integer userId = Integer.valueOf(JwtUtils.getUserIdByJwtToken(request));
        // 2、添加专辑
        int insert = sheetMapper.insert(sheet);
        if (insert!=1){
            return R.error().message("添加歌单失败，系统错误，请联系管理员！");
        }
        // 添加专辑和用户的关联关系
        userMapper.addSheetForUser(sheet.getId(), userId);
        // 3、返回提示信息
        return R.success().message("歌单创建成功！");
    }

    /**
     * 修改歌单
     * 歌单图片，请参考下面的各自的上传方法
     * @param sheet
     * @return
     */
    @Override
    public R updateSheet(Sheet sheet, HttpServletRequest request) {
        // 1、修改前先删除云端文件数据
        Sheet selectOne = sheetMapper.selectById(sheet.getId());
        deleteTXCosSheetImg(selectOne);
        // 对标签去重
        String type = sheet.getType();
        // string 转 数组
        String [] tagArr= type.split(",");
        // 利用 set 进行去重
        Set set = new HashSet();
        //遍历数组并存入集合,如果元素已存在则不会重复存入
        for (int i = 0; i < tagArr.length; i++) {
            set.add(tagArr[i]);
        }
        //返回Set集合的数组形式
//        String[] tagDistinctArr = (String[]) set.toArray();
        String[] tagDistinctArr = (String[])(set.toArray(new String[set.size()]));

        // 数组 转 string
        String tagStr = "";
        for (String tag : tagDistinctArr) {
            tagStr = tagStr + tag + ",";
        }
        sheet.setType(tagStr);
        int updateResult = sheetMapper.updateById(sheet);
        if (updateResult==1){
            return R.success().message("歌单修改成功");
        }
        return R.error().message("歌单修改失败");
    }

    /**
     * 删除歌单
     * 歌单图片，请参考下面的各自的上传方法
     * @param sheetId
     * @return
     */
    @Override
    public R deleteSheet(Integer sheetId, HttpServletRequest request) {
        // 获取登录用户id
        Integer userId = Integer.valueOf(JwtUtils.getUserIdByJwtToken(request));
        // 查询数据库
        Sheet sheet = sheetMapper.selectById(sheetId);
        // 1、删除云存储桶里的数据
        deleteTXCosSheetImg(sheet);
        // 2、删除 歌单在数据库里的基本信息
        sheetMapper.deleteById(sheetId);
        // 3、删除 sheet 和 用户的关联关系
        sheetMapper.deleteUserBySheetId(sheetId);
        // 4、删除 sheet 和 歌曲的关联关系
        sheetMapper.deleteSongBySheetId(sheetId);
        // 5、删除 用户 歌单 我喜欢关联关系
        LambdaQueryWrapper<Love> qw = new LambdaQueryWrapper<>();
        qw.eq(Love::getType, 3);
        qw.eq(Love::getRelevance, sheet.getId());
        qw.eq(Love::getUserId, userId);
        loveMapper.delete(qw);
        return R.success().message("歌单删除成功");
    }

    /**
     * 删除云存储桶里的歌单 图片
     * @param sheet 待删除歌单
     */
    public void deleteTXCosSheetImg(Sheet sheet){
        /*最初爬虫的专辑图片数据没有存到云存储桶 是网易的图片 不需要删，也删不了
        albumImg：http://p1.music.126.net/AAKrMZu-zyunLRqAMO9JlA==/109951166577890720.jpg?param=130y130
        而本系统添加的专辑时，图片是存储在云存储桶里的，需要删除
        albumImg：https://pony-1312090731.cos.ap-beijing.myqcloud.com/yxy/images/20230414093225fcb9570a89b44a1c94421e8239bbe3cf.jpg
        */
        String img = sheet.getImg();

        // 删除云存储桶里的专辑图片
        if (img!=null && !"".equals(img)&&!this.sheetImg.equals(img)){
            //删除云存储桶里的专辑 图片（网易的不用删）, 只需要判断是否以 https 开头就行
            if (img.startsWith("https")){
                //albumImgKey: 20230414093225fcb9570a89b44a1c94421e8239bbe3cf.jpg
                String sheetImgKey = img.substring(img.indexOf("images/")+7);
                TXCloudFileUtils.del(imgPath+sheetImgKey);
            }
        }
    }

    /**
     * 添加歌单-上传专辑图片
     * @param file 图片
     * @return
     */
    @Override
    public R uploadAddImg(MultipartFile file) {
        //1、上传文件 返回值是 key，即图片重新命名的名字
        String imgName = TXCloudFileUtils.upLoad(imgPath, file);
        //2、拼接 img 访问路径，并写入数据库
        String imgUrl = url  + imgPath + imgName;
        return R.success().message("歌单图片上传成功").data("sheetImgUrl", imgUrl);
    }

    /**
     * 为专辑添加歌曲
     * @param sheetId
     * @param request
     * @return
     */
    @Override
    public R addSong(Integer sheetId, Integer songId, HttpServletRequest request) {
        // 1、向查询歌单里是否有这首歌
        List<Song> songList = sheetMapper.selectSongBySheetId(sheetId);
        for (Song song : songList) {
            if (song.getSongId().equals(songId) ){
                return R.error().message("此歌曲已经存在于歌单，无需添加");
            }
        }
        Integer addResult = sheetMapper.addSongForSheet(sheetId, songId);
        if (addResult==1){
            return R.success().message("添加成功");
        }
        return R.error().message("歌曲添加到歌单失败");
    }
}
